package com.yh.shiro.realm;

import com.yh.bean.User;
import com.yh.dao.UserDao;


import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Description: Description
 * @Author: yh
 * @CreateDate: 2018/4/30 21:15
 * @UpdateUser: yh.z
 * @UpdateDate: 2018/4/30 21:15
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
public class CustomRealm extends AuthorizingRealm {
    /*盐*/
    private static final String salt = "salt";
    private static final String REALM_NAME = "CustomRealm";

    /*用户缓存*/
    //private Map<String, String> userMap = new HashMap<>();

    @Autowired
    private UserDao shiroUserDao;

    {
        /*明文*/
        //userMap.put("yh", "123456");
        /*MD5加密*/
        //userMap.put("yh", "e10adc3949ba59abbe56e057f20f883e");
        /*MD5+加盐 salt*/
        //userMap.put("yh", "f51703256a38e6bab3d9410a070c32ea");
        super.setName(REALM_NAME);
        /*加密-交给配置文件*/
//        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
//        hashedCredentialsMatcher.setHashAlgorithmName("md5");
//        hashedCredentialsMatcher.setHashIterations(1);
//        setCredentialsMatcher(hashedCredentialsMatcher);
    }

    /**
     * @Description: 授权
     * @Author: 张颖辉(yh)
     * @Date: 2018/5/4 11:39
     * @param: [principalCollection]
     * @return: org.apache.shiro.authz.AuthorizationInfo
     * @Version: 1.0
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String userName = (String) principalCollection.getPrimaryPrincipal();
        User user = shiroUserDao.getUserByUserName(userName);
        Set<String> roles = getRolesByUserId(user.getId());
        System.out.println("roles=" + roles);
        Set<String> permissions = getPermissionsByRoles(roles);
        System.out.println("permissions=" + permissions);
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(roles);
        simpleAuthorizationInfo.setStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    /**
     * @Description: 认证
     * @Author: 张颖辉(yh)
     * @Date: 2018/5/4 11:39
     * @param: [authenticationToken]
     * @return: org.apache.shiro.authc.AuthenticationInfo
     * @Version: 1.0
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        /*从主体中获得用户名*/
        String userName = (String) authenticationToken.getPrincipal();
        String password = getPasswordByUserName(userName);
        if (password == null)
            return null;
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userName, password, REALM_NAME);
        simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(salt));
        return simpleAuthenticationInfo;
    }

    /**
     * @Description: 获取用户的权限
     * @Author: 张颖辉(yh)
     * @Date: 2018/5/9 21:08
     * @param: [roles]
     * @return: java.lang.String
     * @Version: 1.0
     */
    private Set<String> getPermissionsByRoles(Set<String> roles) {
//        Set<String> permissions = new HashSet<>();
//        permissions.add("user:delete");
//        permissions.add("user:add");
//        permissions.add("user:update");
        List<String> all_permissions = new ArrayList<>();
        for (String role : roles) {
            List<String> permissions = shiroUserDao.getPermissionsByRole(role);
            all_permissions.addAll(permissions);
        }
        return new HashSet<>(all_permissions);
    }


    /**
     * @Description: 从数据库或者缓存中获取角色数据
     * @Author: 张颖辉(yh)
     * @Date: 2018/5/9 21:08
     * @param: [userId]
     * @return: java.lang.String
     * @Version: 1.0
     */
    private Set<String> getRolesByUserId(String userId) {
//        Set<String> roles = new HashSet<>();
//        roles.add("admin");
//        roles.add("user");
        List<String> roles = shiroUserDao.getRolesByUserId(userId);
        return new HashSet<String>(roles);
    }


    /**
     * @Description: 数据库获得用户密码
     * @Author: 张颖辉(yh)
     * @Date: 2018/5/9 21:08
     * @param: [userName]
     * @return: java.lang.String
     * @Version: 1.0
     */
    private String getPasswordByUserName(String userName) {

        // return userMap.get(userName);
        User user = shiroUserDao.getUserByUserName(userName);
        if (user != null) {
            return user.getPassWord();
        }
        return null;
    }

    public static void main(String[] args) {
        Md5Hash md5Hash = new Md5Hash("123456", salt);
        System.out.print(md5Hash);
    }
}
